/**
 * Copyright (C) T-Systems International, 2013-2014
 *
 * The copyright of the computer program herein is the property of
 * T-Systems International. The program may be used and/or copied
 * only with the written permission of T-Systems International or in
 * accordance with the terms and conditions stipulated in the
 * agreement/contract under which the program has been supplied.
 *
 * $Author$
 * $Date$
 * $Rev$
 */
package com.tsystems.migdb.sftp.server;

import lombok.NonNull;
import lombok.extern.log4j.Log4j2;
import org.apache.sshd.server.PublickeyAuthenticator;
import org.apache.sshd.server.session.ServerSession;

import java.nio.file.FileSystems;
import java.nio.file.Files;
import java.nio.file.Path;
import java.security.PublicKey;

@Log4j2
public class MigdbPublickeyAuthenticator implements PublickeyAuthenticator {

    private final Path usersDirectory;
    private final String publicKeyFileName;
    private final OpenSshUtils utils;

    public MigdbPublickeyAuthenticator(@NonNull String usersDirectory, @NonNull String publicKeyFileName,
                                       @NonNull OpenSshUtils utils) {
        Path path = FileSystems.getDefault().getPath(usersDirectory);
        if (!Files.isDirectory(path)) {
            throw new IllegalArgumentException("path must point to a directory");
        }
        this.usersDirectory = path;
        this.publicKeyFileName = publicKeyFileName;
        this.utils = utils;
    }

    @Override
    public boolean authenticate(String username, PublicKey key, ServerSession session) {
        log.debug("Attempting to authenticate {} with public key:\n{}", username, key);
        Path userDirectory = FileSystems.getDefault().getPath(usersDirectory.toString(), username);
        if (!Files.exists(userDirectory)) {
            log.debug("no such user, authentication failed");
            return false;
        }
        Path keyPath = FileSystems.getDefault().getPath(userDirectory.toString(), publicKeyFileName);
        try {
            PublicKey expected = utils.decodePublicKey(Files.readAllBytes(keyPath));
            log.debug("comparing provided public key with the expected one on path {}", keyPath);
            return expected.equals(key);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

}